﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using AutoMapper;

using KSOAdmin.Core.CacheHelper.Interface;
using KSOAdmin.Core.EFDbContext;
using KSOAdmin.Core.Other;
using KSOAdmin.IRepository;
using KSOAdmin.IRepository.System;
using KSOAdmin.IServices.System;
using KSOAdmin.Models.DomainModels.System;

namespace KSOAdmin.Services.System
{
    public class Sys_MenuServices : BasicServices<Sys_Menu>, ISys_MenuServices, IDependency
    {
        private readonly IMapper _mapper;
        private readonly ISys_MenuRepository _menuRepository;
        private readonly ISys_RoleListRepository _RoleListRepository;
        private readonly ICacheService cacheService;
        public Sys_MenuServices(IMapper mapper, ISys_MenuRepository menuRepository, IBasicRepository<Sys_Menu> basic, ISys_RoleListRepository RoleListRepository, ICacheService _cacheService)
        {
            this._RoleListRepository = RoleListRepository;
            this._mapper = mapper;
            this._menuRepository = menuRepository;
            this.repository = basic;
            this.cacheService = _cacheService;
        }

        public async Task<List<Dictionary<string, object>>> GetRoleMenu(bool IsRedis)
        {
            List<Dictionary<string, object>> menu = await GetRoleMenuRedis();
            return menu;
        }

        public async Task<List<Sys_Menu>> GetAllMenu()
        {
            return await _menuRepository.FindListAsync(w => w.Enable == 1);
        }

        public List<Dictionary<string, object>> CreateMenu(int? ID, List<Sys_Menu> menus)
        {
            var menu = menus.Where(w => w.ParentId == ID).OrderBy(w => w.OrderNo).ToList();
            return menu.Select(item => new Dictionary<string, object>
            {
                ["id"] = item.ID,
                ["name"] = item.MenuName,
                ["path"] = item.Url,
                ["meta"] = new { icon = item.Icon, title = item.RMK },
                ["isClose"] = item.Enable,
                ["children"] = this.CreateMenu(item.ID, menus),
                ["redirect"] = ""
            }).ToList();
        }
        private async Task<List<Dictionary<string, object>>> GetRoleMenuRedis()
        {
            List<Sys_RoleList> rolelist = null;
            if (cacheService.Exists(UserObtain.UserId.ToString(), Core.CacheHelper.CacheDataType.UserRole))
            {
                rolelist = cacheService.Get<List<Sys_RoleList>>(UserObtain.UserId.ToString(), Core.CacheHelper.CacheDataType.UserRole);
            }
            else
            {
                rolelist = await this._RoleListRepository.FindListAsync(w => w.Sys_Role_ID == UserObtain.Role_Id);
                await Task.Run(() =>
                {
                    cacheService.AddObject(UserObtain.UserId.ToString(), Core.CacheHelper.CacheDataType.UserRole, rolelist);
                });
            }

            List<Sys_Menu> MenuList = null;
            if (cacheService.Exists(UserObtain.Role_Id.ToString(), Core.CacheHelper.CacheDataType.UserMenu))
            {
                MenuList = cacheService.Get<List<Sys_Menu>>(UserObtain.Role_Id.ToString(), Core.CacheHelper.CacheDataType.UserMenu);
            }
            else
            {
                MenuList = await GetAllMenu();
                await Task.Run(() =>
                {
                    cacheService.AddObject(UserObtain.Role_Id.ToString(), Core.CacheHelper.CacheDataType.UserMenu, MenuList);
                });
            }
            if (MenuList.Count() == 0) return null;
            MenuList = (from a in MenuList
                        join b in rolelist on a.ID equals b.Sys_Menu_Id
                        select a).ToList();
            var menu = CreateMenu(0, MenuList);
            return menu;
        }
        private async Task<List<Dictionary<string, object>>> GetRoleMenuDb()
        {
            List<Sys_Menu> MenuList = await GetAllMenu();
            if (MenuList.Count() == 0)
            {
                return null;
            }
            List<Sys_RoleList> rolelist = await this._RoleListRepository.FindListAsync(w => w.Sys_Role_ID == UserObtain.Role_Id);
            MenuList = (from a in MenuList
                        join b in rolelist on a.ID equals b.Sys_Menu_Id
                        select a).ToList();
            var menu = CreateMenu(0, MenuList);
            return menu;
        }

    }
}
